#pragma once
#include "ModelAnimation.h"
#include "Skeleton.h"
#include <assimp/scene.h>
#include <list>

class ModelAsset;
struct BoneAsset;

static inline glm::mat4 aiMatrix4_cast(const aiMatrix4x4 &mat)
{
    return glm::transpose(glm::make_mat4(&mat.a1));
}

struct ArrayBone{
    int animId;
    int parent;
    glm::mat4 offset;
    glm::mat4 restOffset;
    glm::mat4 bindOffset;
    glm::mat4 baseRestOffsetInverse;

    ArrayBone(){
        parent = -1;
    }

    ArrayBone(int animId, int parent, glm::mat4 restOffset, glm::mat4 bindOffset, glm::mat4 baseRestOffsetInverse)
        : animId(animId), parent(parent), offset(restOffset), restOffset(restOffset), bindOffset(bindOffset), baseRestOffsetInverse(baseRestOffsetInverse)
    {}

    inline void UpdateOffset(glm::mat4 parent, glm::mat4 anim){
        offset = parent * (anim * baseRestOffsetInverse) * restOffset;
        // offset = parent * restOffset;
    }

    inline void UpdateOffset(glm::mat4 parent)
    {
        offset = parent * restOffset;
    }
};

struct Bone
{
    std::string name;
    int id;
    glm::mat4 offset;
    glm::mat4 restOffset;
    glm::mat4 baseRestOffsetInverse;
    glm::mat4 bindOffset;
    std::shared_ptr<Bone> parent;
    std::list<std::shared_ptr<Bone>> children;

    Bone(std::string name, int id, glm::mat4 restOffset, glm::mat4 baseRestOffsetInverse, glm::mat4 bindOffset)
    {
        this->name = name;
        this->id = id;
        this->offset = restOffset;
        this->restOffset = restOffset;
        this->baseRestOffsetInverse = baseRestOffsetInverse;
        this->bindOffset = bindOffset;
    }

    Bone(std::shared_ptr<BoneAsset> boneAsset);

    ~Bone()
    {
        children.clear();
    }

    void UpdateOffset(std::shared_ptr<std::vector<glm::mat4>> animMat4s,
                      std::shared_ptr<std::vector<glm::mat4>> outPutMat4s,
                      std::shared_ptr<std::vector<glm::mat4>> OffsetPutMat4s,
                      glm::mat4 globalOffset);
};
